package com.bygf.curve;

import com.bygf.curve.panel.ChartPanel;
import com.bygf.curve.utils.ToolTipFormat;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

/**
 * 单条曲线类
 *
 * @author sunyupei
 */
public abstract class Curve {

    /**
     * 曲线名称
     */
    protected String name;
    /**
     * 曲线渲染器
     */
    protected CurveRender render = new CurveRender();
    /**
     * 曲线数值转换成的像素点集合X，可直接用来绘制
     */
    protected List<Double> XPixList = new ArrayList<>();
    /**
     * 曲线数值转换成的像素点集合Y，可直接用来绘制
     */
    protected List<Double> YPixList = new ArrayList<>();
    /**
     * 当前可显示曲线数据在数据集合中的序号，用于鼠标悬浮时取数据
     */
    protected int valueIndex = -1;
    /**
     * 使用纵坐标轴2标识
     */
    protected boolean usedY2Axis = false;
    /**
     * 鼠标悬浮格式化对象
     */
    protected ToolTipFormat toolTipFormat = new ToolTipFormat();

    /**
     * 曲线绘制自身方法,将数值通过坐标轴转换成像素
     *
     * @param g
     * @param chartPanel
     */
    public void draw(Graphics2D g, ChartPanel chartPanel) {
        if (!render.isCurveVisible()) {
            return;
        }
        g.setColor(render.getColor());
        g.setStroke(render.getStroke());
        //数值转像素
        this.valueToPix(chartPanel);
        Path2D path = new Path2D.Double();
        for (int i = 0; i < XPixList.size(); i++) {
            if (i == 0) {
                path.moveTo(XPixList.get(i), YPixList.get(i));
            } else {
                path.lineTo(XPixList.get(i), YPixList.get(i));
            }
        }
        g.draw(path);
        Rectangle2D rectLast = null;
        if (render.isShapeVisible()) {
            double width = render.getStroke().getLineWidth() * 4;
            for (int i = 0; i < XPixList.size(); i++) {
                Rectangle2D rect = new Rectangle2D.Double(XPixList.get(i) - width / 2, YPixList.get(i) - width / 2, width, width);
                if (rectLast == null || (rect.getMinX() - rectLast.getMaxX()) > 1) {
                    g.fill(rect);
                    rectLast = rect;
                }
            }
        }
    }

    /**
     * 将曲线数值转成像素点
     *
     * @param chartPanel
     */
    public abstract void valueToPix(ChartPanel chartPanel);

    /**
     * 获取指定位置的鼠标悬浮信息，若不在曲线或曲线数据点上，返回Null，否则返回悬浮信息
     *
     * @param point
     * @return
     */
    public abstract String getToolTip(Point point);

    /**
     * @return the render
     */
    public CurveRender getRender() {
        return render;
    }

    /**
     * @param render the render to set
     */
    public void setRender(CurveRender render) {
        this.render = render;
    }

    /**
     * @return the usedY2Axis
     */
    public boolean isUsedY2Axis() {
        return usedY2Axis;
    }

    /**
     * @param usedY2Axis the usedY2Axis to set
     */
    public void setUsedY2Axis(boolean usedY2Axis) {
        this.usedY2Axis = usedY2Axis;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the toolTipFormat
     */
    public ToolTipFormat getToolTipFormat() {
        return toolTipFormat;
    }

    /**
     * @param toolTipFormat the toolTipFormat to set
     */
    public void setToolTipFormat(ToolTipFormat toolTipFormat) {
        this.toolTipFormat = toolTipFormat;
    }
}
